package com.websocket.java.websocket.handler;

import com.websocket.java.websocket.websocketManager.WsSessionManager;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.BinaryMessage;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.AbstractWebSocketHandler;

import java.time.LocalDateTime;

/**
 * @description: 通过继承AbstractWebSocketHandler类并覆盖相应方法, 可以对websocket的事件进行处理。
 * 除了继承AbstractWebSocketHandler类外,还有以下WebSocketHandler可供选择。
 * AbstractWebSocketHandler可以同时支持普通文本和二进制的消息处理。
 * BinaryWebSocketHandler只支持二进制消息。
 * TextWebSocketHandler只支持普通文本消息。
 * @Author C_Y_J
 * @create 2022/7/7 14:38
 **/
@Slf4j
@Component
public class CustomWebSocketHandler extends AbstractWebSocketHandler {

    /**
     * afterConnectionEstablished方法是在socketQ连接成功后被触发,同原生注解里的@OnOpen功能。
     *
     * @param session
     * @throws Exception
     */
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        log.info("建立ws连接");
        WsSessionManager.add(session.getId(), session);
    }

    /**
     * handleTextMessage方法是在客户端发送普通文件信息时触发,同原生注解里的@OnMessage功能。
     *
     * @param session
     * @param message
     * @throws Exception
     */
    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        log.info("发送文本消息");
        // 获得客户端传来的消息
        String payload = message.getPayload();
        log.info("server 接收到消息 " + payload);
        session.sendMessage(new TextMessage("server 发送给的消息 " + payload + "，发送时间:" + LocalDateTime.now().toString()));
    }

    /**
     * handleBinaryMessage方法是在客户端发送二进制信息时触发,同原生注解里的@OnMessage功能。
     *
     * @param session
     * @param message
     * @throws Exception
     */
    @Override
    protected void handleBinaryMessage(WebSocketSession session, BinaryMessage message) throws Exception {
        log.info("发送二进制消息");
    }

    /**
     * handleTransportError方法同原生注解里的@OnError。
     *
     * @param session
     * @param exception
     * @throws Exception
     */
    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        log.error("异常处理");
        WsSessionManager.removeAndClose(session.getId());
    }

    /**
     * afterConnectionClosed方法是在socket连接关闭后被触发,同原生注解里的@OnClose功能。
     *
     * @param session
     * @param status
     * @throws Exception
     */
    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        log.info("关闭ws连接");
        WsSessionManager.removeAndClose(session.getId());
    }
}

